package com.rui.framework.beans.factory.xml;

import com.rui.framework.beans.BeanDefinition;
import com.rui.framework.beans.MutablePropertyValues;
import com.rui.framework.beans.PropertyValue;
import com.rui.framework.beans.factory.support.BeanDefinitionReader;
import com.rui.framework.beans.factory.support.BeanDefinitionRegistry;
import com.rui.framework.beans.factory.support.SimpleBeanDefinitionRegistry;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.List;

/**
 * @author : [锐神NO.3]
 * @version : [v1.0]
 * @className : XmlBeanDefinitionReader
 * @createTime : [2022/2/26 16:00]
 * @description : [针对xml配置文件进行解析的类]
 */

@SuppressWarnings("all")
public class XmlBeanDefinitionReader implements BeanDefinitionReader {

    /**
     * 声明注册表对象
     */
    private BeanDefinitionRegistry registry;

    public XmlBeanDefinitionReader() {
        registry = new SimpleBeanDefinitionRegistry();
    }

    /**
     * 获取注册表对象
     */
    @Override
    public BeanDefinitionRegistry getRegistry() {
        return registry;
    }

    /**
     * 加载配置文件并在注册表中进行注册
     *
     * @param configLocation
     */
    @Override
    public void loadBeanDefinitions(String configLocation) throws Exception {
        //使用dom4j进行xml配置文件的解析
        SAXReader reader = new SAXReader();

        //获取类路径下的配置文件
        InputStream is = XmlBeanDefinitionReader.class.getClassLoader().getResourceAsStream(configLocation);
        Document document = reader.read(is);

        //根据Document对象获取标签对象
        Element rootElement = document.getRootElement();

        //获取标签对象下的子标签
        List<Element> beanElements = rootElement.elements("bean");

        for (Element beanElement : beanElements) {
            //获取bean标签的id属性
            String id = beanElement.attributeValue("id");

            //获取bean标签的class属性
            String className = beanElement.attributeValue("class");

            //将id属性和class属性封装到BeanDefinition对象中
            //1.创建BeanDefinition对象
            BeanDefinition beanDefinition = new BeanDefinition();
            beanDefinition.setId(id);
            beanDefinition.setClassName(className);

            //创建MutablePropertyValues对象
            MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();

            //获取Bean标签下的所有Property对象
            List<Element> propertyElements = beanElement.elements("property");

            for (Element propertyElement : propertyElements) {
                //获取property标签的name属性
                String name = propertyElement.attributeValue("name");
                String ref = propertyElement.attributeValue("ref");
                String value = propertyElement.attributeValue("value");
                PropertyValue propertyValue = new PropertyValue(name, ref, value);
                mutablePropertyValues.addPropertyValue(propertyValue);
            }

            //将mutablePropertyValues对象添加到beanDefinition对象中
            beanDefinition.setPropertyValues(mutablePropertyValues);

            //将beanDefinition对象添加到注册表中
            registry.registerBeanDefinition(id, beanDefinition);
        }
    }
}
